package com.chen.function_demo.chapter2;

import java.util.List;

/**
 * 第二章第三节
 * @author 陈哲<p>
 * ================================<p>
 * Date: 2025/5/11<p>
 * Time: 18:26<p>
 * ================================
 */
public class Section3 {
    /*
        方法引用：将现有方法的调用转换为函数对象。包含静态方法、实例方法（非静态方法）、构造方法
        方法引用前置条件：是被调用方法的入参和函数的入参一致
        方法引用的语法：
        1、类名::静态方法名；（1、执行此静态方法；2、函数的参数就是该静态方法的参数）；
        eg：(int a, int b) -> Math.max(a,b) ==> Math::max
        2、类名(调用该实例方法的对象的类)::实例方法名 ；（1、执行此对象的实例方法；2、参数：函数的参数除了包含该方法的参数之外，还有一个参数就是该对象）
        eg：(Student stu) -> stu.getName() ==> Student::getName
            (Student stu, String name) -> stu.setName(name) ==> Student::setName
        3、对象::实例方法名；（1、执行此对象的实例方法；2、参数就是此方法的参数）
        eg：(String s) -> System.out.println(s) ==> System.out::println
        4、类名::new ；（1、执行此类的构造方法；2、参数就是构造方法的参数）
        eg：() -> new Student() ==> Student::new 无参构造方法举例
        5、this::非静态方法
        6、super::非静态方法；5、6就是3（对象::非静态方法）的变种，5、6只能在类内部使用
     */

    /**
     * 模拟一个学生类
     */
    static class Student{
        // 姓名
        private String name;
        // 年龄
        private int age;
        // 分数
        private int score;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public int getScore() {
            return score;
        }
        public void setScore(int score) {
            this.score = score;
        }
        public Student(String name, int score, int age) {
            this.name = name;
            this.score = score;
            this.age = age;
        }

        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", score=" + score +
                    '}';
        }
    }

    private static final List<Student> list = List.of(
            new Student("张三", 100, 18),
            new Student("李四", 90, 19),
            new Student("王五", 80, 20),
            new Student("赵六", 70, 21),
            new Student("钱七", 60, 22)
    );

    public static void main(String[] args) {
        // 需求1：获取所有学生成绩大于80分的学生 类名::静态方法名
        System.out.println(list.stream().filter(student -> student.getScore() > 60).toList());
        // 方法引用写法
        System.out.println(list.stream().filter(Section3::isScoreMoreThan80).toList());

        // 需求2：获取所有学生成绩大于80分的学生的姓名 类名::实例方法名
        System.out.println(list.stream().filter(Section3::isScoreMoreThan80).map(student -> student.getName()).toList());
        // 方法引用写法
        System.out.println(list.stream().filter(Section3::isScoreMoreThan80).map(Student::getName).toList());

        // 需求3：打印所有学生基本信息
        list.forEach(stu -> System.out.println(stu));
        // 方法引用写法
        list.forEach(System.out::println);
        // 需求3+：打印所有学生18岁以上的学生姓名 使用对象::方法名
        FilterUtil filterUtil = new FilterUtil();
        System.out.println(list.stream().filter(student -> filterUtil.isAgeMoreThan18(student)).map(student -> student.getName()).toList());
        // 方法引用写法
        System.out.println(list.stream().filter(filterUtil::isAgeMoreThan18).map(Student::getName).toList());
    }

    static boolean isScoreMoreThan80(Student student) {
        return student.getScore() > 80;
    }

    static class FilterUtil{
        public boolean isAgeMoreThan18(Student student) {
            return student.getAge() > 18;
        }
    }
}
